package org.m3;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.m3.R;
import org.m3.puzzle.Block;

import android.app.Activity;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.AbsoluteLayout.LayoutParams;


public class Puzzle  extends Activity implements OnClickListener {
	private int locations[] = new int[] { 0, 0 };
	private List<Block> blocks = new ArrayList<Block>();
	AbsoluteLayout absoluteLayout = null;
	private Block selectedBlock = null;
	//private int itemWidth;
	//private int itemHeight;
	int image;
	private LinearLayout puzzle;
	private int columns = 2;
	private int rows = 3;
	private Dialog dlgCorrect;
    private Button btnGameList;
    private Button btnSpeaker;
    private Button btnNext;
    

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.puzzle);
        
        initBtnGameList();
        initBtnSpeaker();
        initBtnNext();
        
        initGamePlay();
    }
    
    @Override
	public boolean onTouchEvent(MotionEvent event) {
		absoluteLayout.getLocationInWindow(locations);
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				selectedBlock = getBlock(event.getX() - locations[0], event.getY() - locations[1]);
				log("Selected " + blocks.indexOf(selectedBlock));
				return true;
	
			case MotionEvent.ACTION_MOVE:
				if(selectedBlock != null) {
					absoluteLayout.removeView(selectedBlock);
					absoluteLayout.invalidate();
					LayoutParams layoutParams = selectedBlock.getViewLayoutParams();
					int x = (int) (event.getX() - locations[0]);
					int y = (int) (event.getY() - locations[1]);
	
					layoutParams.x = x - (layoutParams.width / 2);
					layoutParams.y = y - (layoutParams.height / 2);
	
					absoluteLayout.addView(selectedBlock, layoutParams);
					absoluteLayout.refreshDrawableState();
					log("Moving " + blocks.indexOf(selectedBlock) + " to " + layoutParams.x + "," + layoutParams.y);
				}
				return true;
			case MotionEvent.ACTION_UP:
				boolean swapped = false;
				if(selectedBlock != null) {
					for(Block endingBlock : blocks) {
						if(!swapped && endingBlock.isTapped(event.getX(), (event.getY() - locations[1]))) {
							// If swapping with itself, restore the position
							if(endingBlock.equals(selectedBlock)) {
								restoreSelected();
							} else {
								LayoutParams newSelectedBlockLayout = endingBlock.getViewLayoutParams();
								LayoutParams newEndingBlockLayout = selectedBlock.getViewLayoutParams();
	
								absoluteLayout.removeView(selectedBlock);
								absoluteLayout.removeView(endingBlock);
	
								absoluteLayout.addView(selectedBlock,
										newSelectedBlockLayout);
								absoluteLayout.addView(endingBlock,
										newEndingBlockLayout);
	
								selectedBlock.setLeft(newSelectedBlockLayout.x);
								selectedBlock.setTop(newSelectedBlockLayout.y);
								endingBlock.setLeft(newEndingBlockLayout.x);
								endingBlock.setTop(newEndingBlockLayout.y);
								log("Swapped " + blocks.indexOf(selectedBlock) + " with " + blocks.indexOf(endingBlock));
								Collections.swap(blocks, blocks.indexOf(selectedBlock), blocks.indexOf(endingBlock));
								absoluteLayout.invalidate();
								swapped = true;
								
								// game finished
								if(isFinished()) {
									getDlgCorrect().show();
				                    new Thread(new Runnable() {
				        				@Override
				        				public void run() {
				        					try {
				        		            	Thread.sleep(2000);
				        		            }catch(InterruptedException e) {
				        		            }
				        		            getDlgCorrect().dismiss();
				        				}
				                    }).start();
								}
							}
						}
					}
				}
				return true;
			default:
				restoreSelected();
				return super.onTouchEvent(event);
		}
	}
    
	@Override
	public void onClick(View v) {
		if(v.equals(btnGameList)) {
			finish();	
		} else if(v.equals(btnSpeaker)) {
    		Home.soundEnabled = !Home.soundEnabled;
    		btnSpeaker.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(Home.soundEnabled ? R.drawable.speaker : R.drawable.dspeaker), null, null);
		} else if(v.equals(btnNext)) {
			columns++;
			rows++;
			initGamePlay();
		}
	}
    
    // PRIVATE METHODS
    
	
	private void initGamePlay() {
        puzzle = (LinearLayout) findViewById(R.id.puzzle);
        puzzle.removeAllViews();
        blocks.clear();
		
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.main);
		Display display = getWindowManager().getDefaultDisplay();
		bitmap = Bitmap.createScaledBitmap(bitmap, display.getWidth(), display.getHeight(), true);
		int width = display.getWidth() / columns;
		int height = display.getHeight() / rows;
		
		absoluteLayout = new AbsoluteLayout(this);

		int count = 0;
		for(int row = 0; row < rows; row++) {
			for(int column = 0; column < columns; column++) {
				Block block = new Block(this, column * width, row * height, width, height, bitmap, count++);
				blocks.add(block);
	        }
		}
		Collections.shuffle(blocks);

		count = 0;
		for(int row = 0; row < rows; row++) {
			for(int column = 0; column < columns; column++) {
				Block block = blocks.get(count++);
				block.setTop(row*height);
				block.setLeft(column*width);
				absoluteLayout.addView(block, new LayoutParams(width, height, column*width, row*height));
			}
		}
		
		puzzle.addView(absoluteLayout);
	}
	
    private void initBtnGameList() {
    	if(btnGameList == null) {
    		btnGameList = (Button) findViewById(R.id.btnGameList);
    		btnGameList.setOnClickListener(this);
    	}
    }

    private void initBtnSpeaker() {
    	if(btnSpeaker == null) {
    		btnSpeaker = (Button) findViewById(R.id.btnSpeaker);
    		btnSpeaker.setOnClickListener(this);
    		btnSpeaker.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(Home.soundEnabled ? R.drawable.speaker : R.drawable.dspeaker), null, null);
    	}
    }

    private void initBtnNext() {
    	if(btnNext == null) {
    		btnNext = (Button) findViewById(R.id.btnNext);
    		btnNext.setOnClickListener(this);
    	}
    }
    
    private boolean isFinished() {
    	boolean ret = true;
    	for(int i=0; i<blocks.size(); i++) {
    		if(blocks.get(i).getSequence() != i) {
    			ret = false;
    			break;
    		}
    	}
    	return ret;
    }

    private Dialog getDlgCorrect() {
    	if(dlgCorrect == null) {
    		dlgCorrect = new Dialog(this);
    		dlgCorrect.setTitle("   " + this.getResources().getString(R.string.correct));
    		dlgCorrect.setContentView(R.layout.result);
            ImageView img = (ImageView) dlgCorrect.findViewById(R.id.imgStatus);
            img.setImageResource(R.drawable.correct);
    	}
    	return dlgCorrect;
    }
    
	private void restoreSelected() {
		LayoutParams originalBlockLayout = selectedBlock.getViewLayoutParams();
		absoluteLayout.removeView(selectedBlock);
		absoluteLayout.addView(selectedBlock, originalBlockLayout);
		selectedBlock.setLeft(originalBlockLayout.x);
		selectedBlock.setTop(originalBlockLayout.y);
	}

	private Block getBlock(float x, float y) {
		log("Block Order = " + blocks.toString());
		for (Block block : blocks) {
			if (block.isTapped(x, y)) {
				return block;
			}
		}
		return null;

	}

	static void log(String msg) {
		Log.d("Picture Puzzle", msg);
	}

}
